package top.hzy520.aop;

import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import top.hzy520.annotation.LogAnnotation;
import top.hzy520.common.constants.Constants;
import top.hzy520.common.resp.ApiResult;
import top.hzy520.common.utils.RequestUtil;
import top.hzy520.log.dao.SysLoginLogMapper;
import top.hzy520.log.dao.SysOperationLogMapper;
import top.hzy520.log.entity.SysLoginLog;
import top.hzy520.log.entity.SysOperationLog;
import top.hzy520.user.entity.User;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.ws.Response;
import java.lang.reflect.Method;

/**
 * @Author: HouZeYu
 * @Description: 日志记录
 * @Date: Created in 22:07 2018/9/18
 */
@Aspect
@Slf4j
@Component
public class LogAop {
    @Autowired
     private SysLoginLogMapper loginLogMapper;
    @Autowired
    private SysOperationLogMapper operationLogMapper;



    private static final Byte LOGIN_SUCCESS = 1;

    private static final Byte LOGIN_FAIL = 2;

    private static final Byte OPERATION_SUCCESS = 1;

    private static final Byte OPERATION_FAIL = 2;
    @Pointcut("@annotation(top.hzy520.annotation.LogAnnotation)")
     public void pointCut(){}
  /**
  *@Author: HouZeYu
  *@Description: 全程切打注解的方法
  *@Date: 21:49 2018/9/20
  */
 @Around(value = "pointCut()")
 public ApiResult after(ProceedingJoinPoint joinPoint) throws Throwable {
     ApiResult result=null;
     System.out.println("");
     LogFactory logFactory=new LogFactory();
   Method method=((MethodSignature)joinPoint.getSignature()).getMethod();
    if (method!=null&&method.isAnnotationPresent(LogAnnotation.class)){
        result= (ApiResult) joinPoint.proceed();
        LogAnnotation logAnnotation=method.getAnnotation(LogAnnotation.class);
        //记录登录日志
        if (logAnnotation.value().equals(LogType.LOGIN.getMessage())){
          //用户登录成功记录登录成功日志
          if (result.getCode()==Constants.RESP_STATUS_OK){
           User user= (User) SecurityUtils.getSubject().getSession().getAttribute("user");
          SysLoginLog loginLog=logFactory.createLoginLog(LogType.LOGIN,user.getRealName(),null,RequestUtil.getIpFromRequest(getServletRequest()),LOGIN_SUCCESS);
          loginLogMapper.insert(loginLog);
          log.info("浏览器版本:"+RequestUtil.getRequestBrowserInfo(getServletRequest()));
          log.info("系统版本:"+RequestUtil.getRequestSystemInfo(getServletRequest()));
          log.info("用户:"+user.getRealName()+"登录成功"+"-----"+"成功记录日志");
          }else {
              //登录失败 记录登录失败的登录日志记录
              //得到切面的登录参数
            User user= (User) joinPoint.getArgs()[0];
            String mesage="账号:"+user.getUsername()+","+"账号密码错误";
              SysLoginLog loginLog=logFactory.createLoginLog(LogType.LOGIN,null,mesage,RequestUtil.getIpFromRequest(getServletRequest()),LOGIN_FAIL);
               loginLogMapper.insert(loginLog);
              log.info("用户:"+user.getUsername()+"登录失败"+"-----"+"成功记录日志");
          }
          return result;
        }else {
            //记录操作日志
            User currentUser= (User) SecurityUtils.getSubject().getSession().getAttribute("user");
            SysOperationLog operationLog=logFactory.createOperationLog(LogType.BUSSINESS,logAnnotation.operationNmae(),currentUser.getId(),joinPoint.getTarget().getClass().getName(),method.getName(),null,null);
            String mesage=null;
            //得到切面的登录参数
            User methodParetemer= (User) joinPoint.getArgs()[0];
            //记录编辑用户的记录
            if (logAnnotation.operationNmae().equals(Constants.EDIT_USER_LOG_NAME)){
               mesage="操作账号:"+currentUser.getUsername()+";被编辑用户ID:"+methodParetemer.getId();
               operationLog.setLogMessage(mesage);
                log.info("用户信息被编辑------"+mesage);
            }
            //记录新增用户记录
            if (logAnnotation.operationNmae().equals(Constants.ADD_USER_LOG_NAME)){
                mesage="操作账号:"+currentUser.getUsername()+";新增用户信息为:"+methodParetemer.toString();
                operationLog.setLogMessage(mesage);
               log.info("新增用户信息:" +mesage);
            }
            //记录删除用户记录
            if (logAnnotation.operationNmae().equals(Constants.DELETE_SINGLE_USER_LOG_NAME)){
                mesage="操作账号:"+currentUser.getUsername()+";删除用户ID为:"+methodParetemer.getId();
                operationLog.setLogMessage(mesage);
                log.info("删除用户信息:" +mesage);
            }
            //记录添加角色记录
            if (logAnnotation.operationNmae().equals(Constants.ADD_ROLE_LOG_NAME)){
                mesage="操作账号:"+currentUser.getUsername()+";新增角色信息为:"+methodParetemer.toString();
                operationLog.setLogMessage(mesage);
                log.info("新增角色信息:" +mesage);
            }
            //记录编辑角色记录
            if (logAnnotation.operationNmae().equals(Constants.EDIT_ROLE_LOG_NAME)){
                mesage="操作账号:"+currentUser.getUsername()+";被编辑角色ID为:"+methodParetemer.getId();
                operationLog.setLogMessage(mesage);
                log.info("被编辑角色ID为:" +mesage);
            }
            //记录删除角色记录
            if (logAnnotation.operationNmae().equals(Constants.DELETE_ROLE_LOG_NAME)){
                mesage="操作账号:"+currentUser.getUsername()+";删除角色ID为:"+methodParetemer.getId();
                operationLog.setLogMessage(mesage);
                log.info("删除角色ID为:" +mesage);
            }
            //设置是否操作成功
            if (result.getCode()==Constants.RESP_STATUS_OK){
                operationLog.setLogStatus(OPERATION_SUCCESS);
            }else {
                operationLog.setLogStatus(OPERATION_FAIL);
            }
            operationLogMapper.insert(operationLog);
            return result;
        }
    }
    return null;
}



public static HttpServletRequest getServletRequest(){
 HttpServletRequest request=((ServletRequestAttributes)RequestContextHolder.currentRequestAttributes()).getRequest();
 return request;
}
    public static HttpServletResponse getServletResponse(){
        HttpServletResponse response=((ServletRequestAttributes)RequestContextHolder.currentRequestAttributes()).getResponse();
        return response;
    }
}
